package com.ruoyi.tcp.client;

import com.ruoyi.tcp.entity.beat.BeatEntity;
import com.ruoyi.tcp.enums.TcpTypeStrEnum;
import com.ruoyi.tcp.messager.CustomerProtocol;
import com.ruoyi.tcp.util.TcpAesUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author 蒋翔 SY100242
 * @date 2024/8/7 15:55
 * @email SY100242@hnlens.com
 */
@Slf4j
public class TestClientCustomerHandler extends SimpleChannelInboundHandler<CustomerProtocol> {
    private static AtomicLong serializeNumber = new AtomicLong(1L);

    @Getter
    public static class ClientChannel {
        private Long channelNo;
        private String password;
        private Integer version;
        private String deviceSerializeNumber;
        private Long deviceNumber;
        private AtomicLong serialNumber ;
        //经度
        private Integer longitude;
        //纬度
        private Integer latitude;
        private String host;
        private Integer port;
    }

    public static final TestClientCustomerHandler.ClientChannel clientChannel;

    static {
        clientChannel = new TestClientCustomerHandler.ClientChannel();
        clientChannel.version = 2;
        clientChannel.channelNo = 101L;
        clientChannel.password = "Z4T6U7RL08VJ5Y36";
        clientChannel.deviceSerializeNumber = "000000000000000000000000";

        clientChannel.serialNumber = new AtomicLong(1L);

        clientChannel.host = "182.254.194.127";
        clientChannel.port = 8883;
    }


    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
//        ctx.close();
        if (evt instanceof IdleStateEvent) {
            //发送心跳
            BeatEntity beatEntity = createBeatEntity(1762726511L, clientChannel.serialNumber.addAndGet(1L));
            ctx.writeAndFlush(beatEntity);
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, CustomerProtocol message) throws Exception {
//        if (log.isDebugEnabled()) {
//            log.debug("\n");
//            log.debug("channelId:{}", ctx.channel().id());
//        }
        Long channelNo = message.getChannelNo();
        if (Objects.isNull(channelNo)) {
            return;
        }
        String password = clientChannel.password;
        if (Objects.isNull(password)) {
//            if (log.isDebugEnabled()) {
//                log.debug("未找到渠道密码:{}", message.getChannelNo());
//            }
            return;
        }
//        log.info("渠道号:" + message.getChannelNo());
//        log.info("收到消息:{}", TcpAesUtil.byte2hex(message.getEncryptData()));

        if (!TcpAesUtil.checkCrc(TcpAesUtil.byte2hex(message.getEncryptData()).getBytes(StandardCharsets.UTF_8))) {
//            log.debug("crc:校验失败");
            return;
        }
        byte[] finalGetData = TcpAesUtil.getNoChannelBytes(message.getEncryptData());
//        log.info("除去渠道数据:{}", TcpAesUtil.byte2hex(finalGetData));
        byte[] finalGetDataNoCrc=new byte[finalGetData.length-2];
        System.arraycopy(finalGetData, 0, finalGetDataNoCrc, 0, finalGetData.length-2);
        byte[] decryptData = TcpAesUtil.decrypt(finalGetDataNoCrc, password);
        //去除补0的数据
        decryptData = TcpAesUtil.removeTrailingZeroBytes(decryptData);
        if (!TcpAesUtil.checkCrc(decryptData)) {
//            log.debug("crc:校验失败");
            return;
        }
        //发送版本
        int version = TcpAesUtil.getVersion(decryptData);
//        log.info("数据版本:{}", version);

        int len = TcpAesUtil.getDataLenth(decryptData);
//        log.info("数据长度:{}", len);

        int serializeNumber = TcpAesUtil.getSerializeNumber(decryptData);
//        log.info("数据序列号:{}", serializeNumber);

        String typeStr = TcpAesUtil.getTypeStr(decryptData);
//        log.info("数据命令类型:{}", typeStr);

        byte[] lenArr = Arrays.copyOfRange(decryptData, 20, 36);
        String deviceNumber = TcpAesUtil.byteArrayToLong(lenArr).toString();
//        log.info("设备编号:" + deviceNumber);
//        ctx.close();
        if(TcpTypeStrEnum.RESPONSE.getValue().equalsIgnoreCase(typeStr)){
            //设备接入成功
            byte[] msgLenArr = Arrays.copyOfRange(decryptData, 36, 44);
            Long l = TcpAesUtil.byteArrayToLong(msgLenArr);
            if (Objects.isNull(l) || l <= 0L) {
                return;
            }
            byte[] bytes = Arrays.copyOfRange(decryptData, 44, decryptData.length - 4);
            String hexStr = new String(bytes, StandardCharsets.UTF_8);
//            log.info("收的消息:{}" , hexStr);
            String o = TcpAesUtil.hexToAscii(hexStr);
//            log.info("收的消息完整:{}" , o);
//            long time = Long.parseLong(o);
//            Instant instant = Instant.ofEpochMilli(time);
//            ZoneId zoneId = ZoneId.systemDefault();
//            LocalDateTime localDateTime =  LocalDateTime.ofInstant(instant, zoneId);
//            log.info("时间为:{}",localDateTime);
        } else if (TcpTypeStrEnum.TIME_SYNC.getValue().equalsIgnoreCase(typeStr)) {
            //时钟同步
            byte[] msgLenArr = Arrays.copyOfRange(decryptData, 36, 40);
            Long l = TcpAesUtil.byteArrayToLong(msgLenArr);
            if (Objects.isNull(l)) {
                return;
            }
            byte[] bytes = Arrays.copyOfRange(decryptData, 40, 40+l.intValue()*2);
            Long time = TcpAesUtil.byteArrayToLong(bytes);
            Instant instant = Instant.ofEpochSecond(time);
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDateTime localDateTime =  LocalDateTime.ofInstant(instant, zoneId);
//            log.info("时间为:{}",localDateTime);
        }


    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        log.info("客户端已建立链接");

//        ReadCustomerMessageEntity entity = new ReadCustomerMessageEntity();
//        entity.setChannelNo(clientChannel.channelNo);
//        entity.setVersion(clientChannel.version);
//        entity.setSerializeNumber(clientChannel.serialNumber.addAndGet(1L));
//        entity.setDeviceSerializeNumber(clientChannel.deviceSerializeNumber);
//        entity.setDeviceNumber(clientChannel.deviceNumber);
//        if (Objects.nonNull(clientChannel.longitude)) {
//            entity.setLongitude(clientChannel.longitude);
//        }
//        if (Objects.nonNull(clientChannel.latitude)) {
//            entity.setLatitude(clientChannel.latitude);
//        }
//        entity.setOccurTime(LocalDateTime.now());
//        entity.setTypeStr("0x2");
//        //读取rfi便签
//        entity.setEncryptData(entity.createEncryptBytes(clientChannel.password));
//        ctx.writeAndFlush(entity);
//
//
//        TimeSyncCustomerEntity timeSyncCustomerEntity = new TimeSyncCustomerEntity();
//        timeSyncCustomerEntity.setChannelNo(clientChannel.channelNo);
//        timeSyncCustomerEntity.setVersion(clientChannel.version);
//        timeSyncCustomerEntity.setSerializeNumber(clientChannel.serialNumber.addAndGet(1L));
//        timeSyncCustomerEntity.setDeviceSerializeNumber(clientChannel.deviceSerializeNumber);
//        timeSyncCustomerEntity.setDeviceNumber(clientChannel.deviceNumber);
//        timeSyncCustomerEntity.setTypeStr("0x5");
//        log.info("发送数据:{}",timeSyncCustomerEntity);
//        timeSyncCustomerEntity.setEncryptData(timeSyncCustomerEntity.createEncryptBytes(clientChannel.password));
//        ctx.writeAndFlush(timeSyncCustomerEntity);

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        log.error("错误:{}",cause.getMessage());
        ctx.close();
    }

    private static BeatEntity createBeatEntity(Long deviceNumber,Long dataSerializenumber) {
        BeatEntity beatEntity = new BeatEntity();
        beatEntity.setChannelNo(clientChannel.channelNo);
        beatEntity.setVersion(clientChannel.version);
        beatEntity.setSerializeNumber(dataSerializenumber);
        beatEntity.setTypeStr("0x1");
        beatEntity.setSendTime(LocalDateTime.now());
        beatEntity.setOccurTime(LocalDateTime.now());
        beatEntity.setDeviceNumber(deviceNumber);
        beatEntity.setDeviceSerializeNumber(clientChannel.deviceSerializeNumber);
        byte[] encryptBytes = beatEntity.createEncryptBytes(clientChannel.password);
        beatEntity.setEncryptData(encryptBytes);
        return beatEntity;
    }
}
